package cn.initcap.concurrency.concurrency.singleton;

import cn.initcap.concurrency.annoations.NotRecomend;
import cn.initcap.concurrency.annoations.NotThreadSafe;

/**
 * 懒汉模式{双重同步锁，非线程安全}
 * <p>
 * 运行步骤：
 * 1.memory = allocate()分配对象的内存空间
 * 2.ctorInstance() 初始化对象
 * 3.instance = memory 设置instance指向刚分配的内存
 * <p>
 * JVM 和cpu 优化发生了指令重排
 * 1.memory = allocate()分配对象的内存空间
 * 3.instance = memory 设置instance指向刚分配的内存
 * 2.ctorInstance() 初始化对象
 *
 * @author initcap
 * @date Created in 2018/6/14 PM12:26.
 */
@NotThreadSafe
@NotRecomend
public class SingletonDoubleCheckLock {

    /**
     * 单例对象
     */
    private static SingletonDoubleCheckLock instance = null;

    /**
     * 私有构造函数
     */
    private SingletonDoubleCheckLock() {

    }

    /**
     * 静态的工厂方法
     */
    public static SingletonDoubleCheckLock getInstance() {
        /**
         * 双重检测机制
         * 加入A线程执行到这里判断instance是否为空，而同时B线程执行第三步，
         * 所以A线程判断instance不为空，而直接去return instance，使用实例，
         * 由于还没有进行初始化，所以会有问题。
         */
        if (instance == null) {
            //同步锁
            synchronized (SingletonDoubleCheckLock.class) {
                if (instance == null) {
                    //B线程在这里先执行了第三步指向分配内存，但是还没有执行第二步，没有初始化对象
                    instance = new SingletonDoubleCheckLock();
                }
            }
        }
        return instance;
    }

}
